home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Workbench Design
/
WB Collection.iso
/
datatypes
/
mrekodt
/
src
/
dispatch.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-04-07
|
7KB
|
239 lines
/*
** dispatch.c - dispatcher for REKO DataType class
** Copyright © 1995 Michael Letowski
*/
#include <exec/types.h>
#include <exec/memory.h>
#include <dos/dos.h>
#include <graphics/displayinfo.h>
#include <graphics/gfx.h>
#include <graphics/modeid.h>
#include <intuition/classes.h>
#include <datatypes/datatypesclass.h>
#include <datatypes/pictureclass.h>
#include <utility/hooks.h>
#include <support/types.h>
#include <string.h>
#include <proto/dos.h>
#include <proto/exec.h>
#include <proto/datatypes.h>
#include <proto/graphics.h>
#include <proto/intuition.h>
#include <proto/utility.h>
#include "classbase.h"
#include "dispatch.h"
#define HCNT 13 /* Number of cards horizontally */
#define VCNT 4 /* Number of cards vertically */
#define REKO_I 55 /* Cards in REKO I cardset */
#define REKO_II 59 /* Cards in REKO II cardset */
struct Map
{
ULONG map_X;
ULONG map_Y;
};
STATIC ASM Object *Dispatch(R_A0 Class *cl, R_A2 Object *o, R_A1 Msg msg);
//STATIC ASM LBOOL GetREKO(R_A6 struct ClassBase *cb, R_A0 Class *cl,
// R_A2 Object *o, R_A1 struct TagItem *attrs);
STATIC LBOOL GetREKO(struct ClassBase *cb, Object *o, struct TagItem *attrs);
STATIC VOID GetXY(ULONG num, ULONG *x, ULONG *y);
STATIC ULONG LocSetDTAttrs(struct ClassBase *cb, Object *o, ULONG data, ...);
STATIC ULONG LocGetDTAttrs(struct ClassBase *cb, Object *o, ULONG data, ...);
Class *InitClass(struct ClassBase *cb)
{
Class *CL;
/* Create our class (no instance) */
if(CL=MakeClass(REKODTCLASS,PICTUREDTCLASS,NULL,NULL,0))
{
CL->cl_Dispatcher.h_Entry=(HOOKFUNC)Dispatch;
CL->cl_UserData=(ULONG)cb;
AddClass(CL);
}
return(CL);
} /* InitClass */
STATIC ASM Object *Dispatch(R_A0 Class *cl, R_A2 Object *o, R_A1 Msg msg)
{
struct ClassBase *cb=(struct ClassBase *)cl->cl_UserData;
Object *Obj;
switch(msg->MethodID)
{
case OM_NEW: /* We know this method */
if(Obj=(Object *)DoSuperMethodA(cl,o,msg))
unless(GetREKO(cb,Obj,((struct opSet *)msg)->ops_AttrList))
{
CoerceMethod(cl,Obj,OM_DISPOSE);
return(NULL);
}
break;
default: /* Let the superclass handle it */
Obj=(Object *)DoSuperMethodA(cl,o,msg);
break;
}
return(Obj);
}
STATIC LBOOL GetREKO(struct ClassBase *cb, Object *o, struct TagItem *attrs)
{
struct RekoHeader Header;
struct BitMapHeader *BMHD=NULL;
struct BitMap *BM;
struct ColorRegister *CMAP=NULL;
LONG *CRegs=NULL;
MPTR Buffer,SrcPtr; /* Buffer for reading */
STRPTR Title; /* Picture name */
BPTR FH=0; /* File handle */
ULONG ModeID; /* Display mode */
ULONG HCnt,Cards,Height,Width,Depth,LSize,CSize;
ULONG BPR,DstOffs,X,Y,I,J,K;
/* Get default title */
Title=(STRPTR)GetTagData(DTA_Name,NULL,attrs);
/* Get file handle and BitMapHeader */
LocGetDTAttrs(cb,o,DTA_Handle,&FH,PDTA_BitMapHeader,&BMHD,TAG_DONE);
try(FH && BMHD, EXIT) /* File handle or header not supplied */
try(Seek(FH,0,OFFSET_BEGINNING)>=0, EXIT); /* Position at the beginnig of file */
try(Read(FH,&Header,HEADER_SIZE)==HEADER_SIZE, EXIT);
if(Header.rh_ID!=REKO_ID) /* Not REKO */
{
SetIoErr(ERROR_OBJECT_WRONG_TYPE); /* Inform caller */
throw(EXIT);
}
/* Calculate sizes */
Width=Header.rh_Width;
Height=Header.rh_Height;
Depth=Header.rh_Depth;
Cards=Header.rh_Cards;
LSize=Width>>3; /* Width in bytes */
CSize=LSize*Height*Depth; /* Card size in bytes */
if(Header.rh_SingleSize!=CSize ||
Header.rh_BodySize!=CSize*Cards+CTABLE_SIZE || Cards==0)
{ /* Do internal checking */
SetIoErr(ERROR_OBJECT_WRONG_TYPE); /* Inform caller */
throw(EXIT);
}
/* Calculate number of horizonatal cards */
HCnt=(Cards==REKO_I) ? 14 :
((Cards==REKO_II) ? 16 : Cards/VCNT+(Cards%VCNT>0));
BMHD->bmh_Width=Width*HCnt; /* Fill in informations */
BMHD->bmh_Height=Height*VCNT;
BMHD->bmh_Depth=Depth;
/* Get display mode id */
if(ModeNotAvailable(Header.rh_ModeID)==0) /* Good mode */
ModeID=Header.rh_ModeID;
else /* Calculate mode */
{
ModeID=BestModeID(BIDTAG_DIPFMustHave, DIPF_IS_HAM,
BIDTAG_DesiredWidth, BMHD->bmh_Width,
BIDTAG_DesiredHeight, BMHD->bmh_Height,
BIDTAG_Depth, BMHD->bmh_Depth,
BIDTAG_SourceID, HIRESHAMLACE_KEY,TAG_DONE);
if(ModeID==INVALID_ID)
ModeID=HIRESHAMLACE_KEY;
}
/* Get colors */
LocSetDTAttrs(cb,o,PDTA_NumColors,1<<BMHD->bmh_Depth,TAG_DONE);
LocGetDTAttrs(cb,o,PDTA_ColorRegisters,&CMAP,PDTA_CRegs,&CRegs,TAG_DONE);
try(CMAP && CRegs, EXIT);
try(Read(FH,CMAP,CTABLE_SIZE)==CTABLE_SIZE, EXIT);
/* Set remap palette */
for(I=0; I<1<<BMHD->bmh_Depth; I++)
{
CRegs[I*3+0]=CMAP[I].red<<24;
CRegs[I*3+1]=CMAP[I].green<<24;
CRegs[I*3+2]=CMAP[I].blue<<24;
}
/* Prepare bitmap */
try(BM=AllocBitMap(BMHD->bmh_Width,BMHD->bmh_Height,BMHD->bmh_Depth,
BMF_CLEAR | BMF_INTERLEAVED | BMF_DISPLAYABLE,NULL),
NO_BITMAP);
BPR=BM->BytesPerRow;
/* Read data */
try(Buffer=AllocVec(CSize,MEMF_PUBLIC), NO_MEM);
for(I=0; I<Cards; I++)
{
try(Read(FH,Buffer,CSize)==CSize, BODY_ERR);
GetXY(I,&X,&Y); /* Get coordinates */
SrcPtr=Buffer;
DstOffs=Y*Height*BPR+X*LSize;
for(J=0; J<Height; J++)
{
for(K=0; K<Depth; K++)
{
memcpy(BM->Planes[K]+DstOffs,SrcPtr,LSize);
SrcPtr+=LSize;
}
DstOffs+=BPR;
}
}
FreeVec(Buffer);
/* Set attributes of destination picture */
LocSetDTAttrs(cb,o,DTA_ObjName,Title,
DTA_NominalHoriz, BMHD->bmh_Width,
DTA_NominalVert, BMHD->bmh_Height,
PDTA_BitMap, BM,
PDTA_ModeID, ModeID,
TAG_DONE);
return(TRUE);
/* Exceptions */
except(BODY_ERR, );
except(NO_MEM, FreeVec(Buffer));
except(NO_BITMAP, FreeBitMap(BM));
except(EXIT, );
return(FALSE);
} /* GetREKO */
STATIC VOID GetXY(ULONG num, ULONG *x, ULONG *y)
{
STATIC CONST struct Map Mapping[]=
{
{HCNT,0}, {HCNT,1}, {HCNT,1},
{HCNT,3}, {HCNT+1,3}, {HCNT+2,3}, {HCNT,2}
};
if(num<3)
{
*x=Mapping[num].map_X;
*y=Mapping[num].map_Y;
}
else if(num>54 && num<59)
{
*x=Mapping[num-52].map_X;
*y=Mapping[num-52].map_Y;
}
else
{
*x=(num-3)/VCNT;
*y=(num-3)%VCNT;
}
} /* GetXY */
STATIC ULONG LocSetDTAttrs(struct ClassBase *cb, Object *o, ULONG data, ...)
{
return(SetDTAttrsA(o,NULL,NULL,(struct TagItem *)&data));
} /* LocSetDTAttrs */
STATIC ULONG LocGetDTAttrs(struct ClassBase *cb, Object *o, ULONG data, ...)
{
return(GetDTAttrsA(o,(struct TagItem *)&data));
} /* LocGetDTAttrs */